local _G, print, tonumber, event, pairs, tostring
    = _G, print, tonumber, event, pairs, tostring

module 'Properties'

local properties = {} -- tabela que armazena as variáveis controladas pela biblioteca 
local listeners = {} -- tabela que armazena os interessados em atribuições de variáveis

-- 'método' de atribuição de uma variável: armazena a variável e lança eventos de inicio e fim de atribuição
function set (property, value)
    value = tostring(value)
    properties[property] = value
    evt = {class = 'ncl', type = 'attribution', name = property, value = value}
    evt.action = 'start'; event.post(evt)
    evt.action = 'stop';  event.post(evt)
end

-- 'método' que utilizado para obter o valor de uma propriedade: se apropriedade não existir retorna um valor padrão
function get (property, default)
    value = properties[property]
    if value then
        return value
    else
        return default
    end
end


-- 'método' de registro funções tratadoras interessadas na atribuição de variáveis: pode receber uma propriedade como parâmetro, ou registrar a função para ser notificada sobre todas as atribuições.
function register (f, property)
    if property then
        listeners[f] = property
    else
        listeners[f] = true
    end
end

-- função que notifica a atribuição de variáveis aos interessados
local function on_set (property, value)
    for f, v in pairs(listeners) do
        if v == true or v == property then
            f(property, value)
        end
    end
end

-- 'método de desregstro de funções tratadoras'
function unregister (f)
    listeners[f] = nil
end

-- define uma função tratadora de eventos da classe 'ncl' do tipo 'attribution'
local function handler (evt)
    if evt.class == 'ncl' and evt.type == 'attribution' then
       -- ao receber um evento de atribuição, armazena o valor, confirma a atribuição e notifica os interessados na atribuição da variável
       properties[evt.name] = evt.value
       evt.action = 'stop' ; event.post(evt)
       on_set (evt.name, evt.value)
    end
end

event.register(handler)
